<template>
  <el-dialog :visible.sync="visible"
             @click.native="roleVisible = false"
             :title="!dataForm.id ? `${$t('add')}角色` : `修改角色`"
             :close-on-click-modal="false"
             :append-to-body="true"
             :before-close="closeDialog"
             label-position="top"
             class="add-or-updata"
             width="40%"
             :close-on-press-escape="false">
    <el-form :model="dataForm"
             :rules="dataRule"
             ref="dataForm"
             label-position="left"
             v-loading='dataListLoading'
             @keyup.enter.native="dataFormSubmitHandle()"
             label-width="80px">
      <el-form-item prop="roleName"
                    label="角色名称">
        <el-input v-model.trim="dataForm.roleName"
                  placeholder="角色名称"
                  show-word-limit></el-input>
      </el-form-item>
      <el-form-item prop="remake"
                    label="备注">
        <el-input v-model="dataForm.remake"
                  type="textarea"
                  show-word-limit
                  resize="none"
                  :autosize="{ minRows: 2, maxRows: 3}"
                  placeholder="请输入备注内容"></el-input>
      </el-form-item>
      <el-form-item label="选择权限"
                    v-loading='ruleLoading'>
        <div class="rule-list-box">
          <div class="rule-list">
            <!-- <el-input placeholder="输入关键字进行过滤"
                      v-model="filterText">
            </el-input> -->
            <!-- default-expand-all -->
            <el-tree :data="ruleTree"
                     show-checkbox
                     default-expand-all
                     ref="ruleTree"
                     :check-strictly="true"
                     :props="defaultProps"
                     :filter-node-method="filterNode"
                     @check-change="ruleChange"
                     node-key="id">
              <span class="custom-tree-node"
                    slot-scope="{ node, data }">
                <span>{{ node.label }}</span>
                <span v-if="isAllCheck(data)"
                      class="margin-left-10">
                  <el-button type="text"
                             size="mini"
                             @click.stop="setCheckAll(data)">
                    全选
                  </el-button>
                </span>
              </span>
            </el-tree>
          </div>
        </div>
      </el-form-item>
    </el-form>
    <template slot="footer">
      <el-button type="primary"
                 :loading="ruleLoading"
                 @click="dataFormSubmitHandle()"
                 :disabled="enableConfig">{{ $t('confirm') }}</el-button>
      <el-button @click="closeDialog">{{ $t('cancel') }}</el-button>
    </template>
  </el-dialog>
</template>

<script>
import formValidate from '@/mixins/form-validate'
import mixinViewModule from '@/mixins/view-module'
import debounce from 'lodash/debounce'
export default {
  mixins: [mixinViewModule, formValidate],
  data () {
    return {
      visible: false,
      user: {},
      menuList: [],
      enableConfig: false, // 确认之后禁用掉按钮，等操作成功之后恢复
      mixinViewModuleOptions: {
        getDataInfoURL: '/sys/role/getRole?id=', // 获取角色管理的详情
        getRuleListURL: '/sys/role/perByRole', // 根据上级角色id获取对应的菜单树结构
        addURL: '/sys/role/insertRole', // 新增或添加的接口
        updateURL: '/sys/role/updateRole' // 新增或添加的接口

      },
      roleVisible: false,
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      actionItems: [], // 选中的菜单id
      ruleLoading: false,
      actionRules: {},
      deletRules: [],
      ruleTree: [],
      roleTree: [],
      filterText: '',
      dataForm: {
        id: '',
        roleName: '',
        remake: '',
        permissions: []
      }
    }
  },
  watch: {
    filterText (val) {
      this.$refs.ruleTree.filter(val)
    }
  },
  computed: {
    isAllCheck () {
      return (val) => {
        return !!val.children.length
      }
    },
    dataRule () {
      return {
        roleName: [
          { required: true, message: this.$t('validate.required'), trigger: 'change' },
          { min: 0, max: 100, message: '长度在 1 到 100 个字符', trigger: 'change' }
        ],
        remake: [
          { required: false, message: this.$t('validate.required'), trigger: 'change' },
          { min: 0, max: 100, message: '长度在 0 到 100 个字符', trigger: 'change' }
        ]
      }
    }
  },
  methods: {
    filterNode (value, data) {
      if (!value) return true
      return data.name.indexOf(value) !== -1
    },
    closeDialog () {
      this.visible = false
      this.ruleLoading = false
      this.$refs['dataForm'].resetFields()
      this.checkList = []
    },
    init (data) {
      // data = data || {}
      this.visible = true
      this.ruleLoading = false
      this.dataForm.id = data
      this.actionItems = []
      this.roleTree = []
      this.ruleTree = []
      this.dataForm.permissions = []
      this.deletRules = []
      this.dataForm.pid = ''
      if (data) {
        this.getDataInfo()
        this.getRuleList()
      } else {
        this.getRoleList()
      }
      // })
    },
    // 全选
    setCheckAll (node) {
      // 获取选中菜单的所有子级
      const ids = this.getCheckMenuChildren(node, true)
      const temp = this.actionItems.concat(ids)
      this.actionItems = []
      this.actionItems.push(...new Set(temp))
      this.$refs.ruleTree.setCheckedKeys(this.actionItems)
    },
    // 修改获取的权限
    ruleChange (node, check) {
      this.dataForm.permissions = []
      this.deletRules = []
      let rules = JSON.parse(JSON.stringify(this.actionRules))
      // 是否选中
      if (check) {
        // 获取当前选中菜单的顶级目录
        const topItem = this.ruleTree.filter(item => item.id === node.topId || item.id === node.id)
        // 获取当前菜单的所有父级id，将当前选中菜单的父级id和之前的id进行并和
        // const ids = this.getMenuParant(node, topItem[0])
        const ids = this.getMenuParant(node.id, topItem, topItem)
        const temp = this.actionItems.concat(ids)
        // 清空当前选中的菜单数组并添加新的数据选中菜单数据
        this.actionItems = []
        this.actionItems.push(...new Set(temp))
      } else {
        // 获取选中的菜单的已选中的子级
        const deleteList = this.getCheckMenuChildren(node)
        deleteList.map(deletItem => {
          this.actionItems.map((item, index) => {
            if (item === deletItem) {
              this.actionItems.splice(index, 1)
            }
          })
        })
      }

      this.actionItems.map(item => {
        this.dataForm.permissions.push({
          id: item
          // roleId: this.dataForm.id
        })

        if (rules[item]) {
          delete rules[item]
        }
      })

      this.deletRules.push(...Object.values(rules))
      this.$refs.ruleTree.setCheckedKeys(this.actionItems)
    },
    // 获取菜单树结构
    getRoleList () {
      this.ruleLoading = true
      this.$http.get('/sys/role/allPermission').then(({ data: res }) => {
        this.ruleLoading = false
        this.selectMenu(res.data)
      })
      // this.getData({
      //   url: this.mixinViewModuleOptions.getRoleListURL,
      //   isLoading: false
      // })
      //   .then(res => {
      //     this.selectMenu(res.data)
      //   })
    },
    getRuleList () {
      this.ruleLoading = true
      this.getDataList({
        url: this.mixinViewModuleOptions.getRuleListURL,
        isLoading: false,
        paramData: { id: this.dataForm.id }
      })
        .then(res => {
          this.selectMenu(res.data)
        })
    },
    // 设置已选中的菜单权限
    selectMenu (data) {
      this.ruleTree = []
      this.actionRules = {}
      this.ruleLoading = false
      this.$refs.ruleTree.setCheckedKeys([])
      this.dataForm.permissions = []
      this.actionItems = []

      this.getSelectMenu(data)
      this.$refs.ruleTree.setCheckedKeys(Object.values(this.actionRules), true)
      this.ruleTree.push(...data)
    },
    /**
     * @method: getCheckMenuChildren
     * @msg: 递归查找当前选中菜单的下级
     * @param  {Object} actionItem  // 选中的菜单项
     * @param  {Boolean} allChildren  // 是否获取该选中菜单的所有子级， 默认false
     * @param  {Array} ids  // 选中菜单项的ids
     * @return {Array} ids
     */
    getCheckMenuChildren (actionItem, allChildren, ids) {
      ids = ids || []
      let filterItem = []
      ids.push(actionItem.id)

      actionItem.children.map(childrenItem => {
        if (!allChildren) {
          filterItem = this.actionItems.filter(item => item === childrenItem.id)
        }

        if (filterItem.length || allChildren) {
          ids = this.getCheckMenuChildren(childrenItem, !!allChildren, ids)
        }
      })

      return ids
    },
    // 递归查找当前选中菜单的所有父级
    getMenuParant (id, list, initialList, ids) {
      ids = ids || []

      for (var i = 0; i < list.length; i++) {
        var item = list[i]
        if (item.id === id) {
          ids.push(item.id)

          this.getMenuParant(item.pid, initialList, initialList, ids)
          break
        } else {
          if (item.children.length) {
            this.getMenuParant(id, item.children, initialList, ids)
          }
        }
      }
      return ids
    },
    // 递归查询已勾选的菜单权限
    getSelectMenu (list) {
      list.map(item => {
        if (item.sign) {
          this.$set(this.actionRules, item.id, item.id)
          this.actionItems.push(item.id)
          this.dataForm.permissions.push({
            id: item.id
          })
          if (item.children.length) {
            this.getSelectMenu(item.children)
          }
        }
      })
    },
    // 获取信息
    getInfo (data) {
      this.$http.get(`/sys/role/perByRole?id=${data}`).then(({ data: res }) => {
        if (res.code !== 0) { return false }
        this.selectMenu(res.data)
      })
    },
    // 表单提交
    dataFormSubmitHandle: debounce(function () {
      // this.dataForm.delMenuIdList = this.deletRules
      if (this.dataForm.roleName === '') {
        return this.$message.warning('请填写角色名称')
      }
      if (this.dataForm.permissions.length === 0) {
        return this.$message.warning('请选择权限')
      }
      const url = this.dataForm.id ? this.mixinViewModuleOptions.updateURL : this.mixinViewModuleOptions.addURL
      if (this.dataForm.id) {
        this.$confirm('是否把该角色新增加的权限同步给对应的用户, 是否继续?', '提示', {
          confirmButtonText: '是',
          cancelButtonText: '否',
          type: 'warning'
        }).then(() => {
          this.dataForm.criteria = '1'
          this.addOrUpdateItem({ url }).then(res => {
            if (res.code !== 0) { return }
            this.closeDialog()
            this.$emit('callBack')
          })
        }).catch(() => {
          this.addOrUpdateItem({ url }).then(res => {
            if (res.code !== 0) { return }
            this.closeDialog()
            this.$emit('callBack')
          })
        })
      } else {
        this.addOrUpdateItem({ url }).then(res => {
          if (res.code !== 0) { return }
          this.closeDialog()
          this.$emit('callBack')
        })
      }
    }, 1000, { 'leading': true, 'trailing': false })
  }
}
</script>
<style lang="scss" scoped>
.rule-list-box {
  position: relative;
  width: 100%;
  height: 210px;
  overflow: hidden;
  .rule-list {
    position: absolute;
    top: 0;
    left: 0;
    width: 105%;
    max-height: 210px;
    overflow: hidden;
    overflow-y: auto;
  }
}
</style>
